﻿//------------------------------------------------------------------------------
//  Namespace: FruitVentDesign.Utils
//  
//  Function： N/A
//  Name： UITools
//  
//  Ver       Time                     Author
//  0.10      2021/6/27 22:02:32      FruitVent
//
//  此代码版权归作者本人FruitVent所有
//  源代码使用协议遵循本仓库的开源协议及附加协议，若本仓库没有设置，则按MIT开源协议授权
//  CSDN博客：https://blog.csdn.net/weixin_39552347
//  源代码仓库：https://gitee.com/fruitvent
//  感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Media;

namespace FruitVentDesign.Utils
{
    public delegate Point GetDragDropPosition(IInputElement theElement);

    public class UITools
    {

        /// <summary>
        /// Method checks whether the mouse is on the required Target
        /// Input Parameter (1) "Visual" -> Used to provide Rendering support to WPF
        /// Input Paraneter (2) "User Defined Delegate" positioning for Operation
        /// </summary>
        /// <param name="theTarget"></param>
        /// <param name="pos"></param>
        /// <returns>The "Rect" Information for specific Position</returns>
        private static bool IsTheMouseOnTargetRow(Visual theTarget, GetDragDropPosition pos)
        {
            if (theTarget == null) return false;
            Rect posBounds = VisualTreeHelper.GetDescendantBounds(theTarget);
            Point theMousePos = pos((IInputElement)theTarget);
            return posBounds.Contains(theMousePos);
        }


        /// <summary>
        /// Returns the selected DataGridRow
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        private static DataGridRow GetDataGridRowItem(int index, DataGrid dgEmployee)
        {
            if (dgEmployee.ItemContainerGenerator.Status
                    != GeneratorStatus.ContainersGenerated)
                return null;

            return dgEmployee.ItemContainerGenerator.ContainerFromIndex(index)
                                                            as DataGridRow;
        }


        /// <summary>
        /// Returns the Index of the Current Row.
        /// </summary>
        /// <param name="pos"></param>
        /// <returns></returns>
        public static int GetDataGridItemCurrentRowIndex(GetDragDropPosition pos, DataGrid dgEmployee)
        {
            int curIndex = -1;
            for (int i = 0; i < dgEmployee.Items.Count; i++)
            {
                DataGridRow itm = GetDataGridRowItem(i, dgEmployee);
                if (IsTheMouseOnTargetRow(itm, pos))
                {
                    curIndex = i;
                    break;
                }
            }
            return curIndex;
        }

        /// <summary>
        /// Returns the selected DataGridRow
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        private static ListBoxItem GetListBoxItem(int index, ListBox listBox)
        {
            if (listBox.ItemContainerGenerator.Status
                    != GeneratorStatus.ContainersGenerated)
                return null;

            return listBox.ItemContainerGenerator.ContainerFromIndex(index) as ListBoxItem;
        }

        /// <summary>
        /// Returns the Index of the Current Row.
        /// </summary>
        /// <param name="pos"></param>
        /// <returns></returns>
        public static int GetListBoxItemCurrentRowIndex(GetDragDropPosition pos, ListBox listBox)
        {
            int curIndex = -1;
            for (int i = 0; i < listBox.Items.Count; i++)
            {
                ListBoxItem itm = GetListBoxItem(i, listBox);
                if (IsTheMouseOnTargetRow(itm, pos))
                {
                    curIndex = i;
                    break;
                }
            }
            return curIndex;
        }

        /// <summary>
        /// find visual parent
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static T FindVisualParent<T>(DependencyObject obj) where T : class
        {
            while (obj != null)
            {
                if (obj is T)
                {
                    return obj as T;
                }
                obj = VisualTreeHelper.GetParent(obj);
            }

            return null;
        }

        public static T FindFirstChild<T>(FrameworkElement element) where T : FrameworkElement
        {
            int childrenCount = VisualTreeHelper.GetChildrenCount(element);
            var children = new FrameworkElement[childrenCount];

            for (int i = 0; i < childrenCount; i++)
            {
                var child = VisualTreeHelper.GetChild(element, i) as FrameworkElement;
                children[i] = child;
                if (child is T)
                    return (T)child;
            }

            for (int i = 0; i < childrenCount; i++)
                if (children[i] != null)
                {
                    var subChild = FindFirstChild<T>(children[i]);
                    if (subChild != null)
                        return subChild;
                }

            return null;
        }
    }
}
